Loading and Running Yarn Scripts
Welcome to the YarnRunner functionality tutorial. In this tutorial, we will guide you on how to load and run the Yarn narrative scripts you wrote in the previous tutorial.
1. Initializing YarnRunner
- Lua
- Teal
- YueScript
First, make sure you have correctly imported all the necessary modules. Here are the modules we need for the examples in this tutorial:
local Content <const> = require("Content")
local Path <const> = require("Path")
local Node <const> = require("Node")
local Director <const> = require("Director")
local YarnRunner <const> = require("YarnRunner")
To ensure that we can locate the Yarn script, we need to set the correct search path. If the Yarn script and program modules are in the same directory, you can add the following code:
local path = Path:getScriptPath(...)
Content:insertSearchPath(1, path)
Next, assuming we want to load a Yarn file named "tutorial.yarn" with a starting node titled "Start," you can write the following code:
local runner = YarnRunner("tutorial.yarn", "Start")
First, make sure you have correctly imported all the necessary modules. Here are the modules we need for the examples in this tutorial:
local Content <const> = require("Content")
local Path <const> = require("Path")
local Node <const> = require("Node")
local Director <const> = require("Director")
local YarnRunner <const> = require("YarnRunner")
To ensure that we can locate the Yarn script, we need to set the correct search path. If the Yarn script and program modules are in the same directory, you can add the following code:
local path = Path:getScriptPath(...)
Content:insertSearchPath(1, path)
Next, assuming we want to load a Yarn file named "tutorial.yarn" with a starting node titled "Start," you can write the following code:
local runner = YarnRunner("tutorial.yarn", "Start")
First, make sure you have imported all the necessary modules.
_ENV = Dora!
import "YarnRunner"
To ensure that we can locate the Yarn script, we need to set the correct search path. If the Yarn script and program modules are in the same directory, you can add the following code:
path = Path\getScriptPath ...
Content\insertSearchPath 1, path
Next, assuming we want to load a Yarn file named "tutorial.yarn" with a starting node titled "Start," you can write the following code:
runner = YarnRunner "tutorial.yarn", "Start"
2. Executing and Displaying Narrative Content
We have defined an advance
function that can read and display text content or options from the Yarn script. Depending on the narrative content, it can also display character names:
- Lua
- Teal
- YueScript
-- The `advance` function takes an optional integer parameter representing the player's choice index.
-- When calling this function for the first time or when no choice is needed, we pass nil.
local function advance(option)
-- The function first calls `runner:advance(option)` to fetch the next part of the Yarn script.
-- This returns two values: an action type and a result.
local action, result = runner:advance(option)
-- Based on the action type, we choose how to handle the result.
if action == "Text" then
-- If the action is "Text," the result will be a TextResult object,
-- which contains the text content and any associated marks (e.g., character names).
-- We check for marks, extract the character name (if present), and print the text content.
local characterName = ""
local marks = result.marks
if marks then
for i = 1, #marks do
local mark = marks[i]
if mark.name == "char" then
characterName = mark.attrs.name .. ": "
end
end
end
print(characterName .. result.text)
elseif action == "Option" then
-- If the action is "Option," the result will be an OptionResult object,
-- which contains one or more options. The function iterates through these options and prints them,
-- which the player can choose later.
for i, op in ipairs(result) do
if op then
print("[" .. tostring(i) .. "]: " .. op.text)
end
end
else
-- For other actions (e.g., errors), the function directly prints the result.
print(result)
end
end
-- The `advance` function takes an optional integer parameter representing the player's choice index.
-- When calling this function for the first time or when no choice is needed, we pass nil.
local function advance(option?: integer)
-- The function first calls `runner:advance(option)` to fetch the next part of the Yarn script.
-- This returns two values: an action type and a result.
local action, result = runner:advance(option)
-- Based on the action type, we choose how to handle the result.
if action == "Text" then
-- If the action is "Text," the result will be a TextResult object,
-- which contains the text content and any associated marks (e.g., character names).
-- We check for marks, extract the character name (if present), and print the text content.
local textResult = result as YarnRunner.TextResult
-- Check for marks, extract character name (if present), and print text content.
local characterName = ""
local marks = textResult.marks
if not (marks is nil) then
for i = 1, #marks do
local mark = marks[i]
if mark.name == "char" then
characterName = tostring(mark.attrs.name) .. ": "
end
end
end
print(characterName .. textResult.text)
elseif action == "Option" then
-- If the action is "Option," the result will be an OptionResult object,
-- which contains one or more options. The function iterates through these options and prints them,
-- which the player can choose later.
local optionResult = result as YarnRunner.OptionResult
for i, op in ipairs(optionResult) do
if op and not (op is boolean) then
print("[" .. tostring(i) .. "]: " .. op.text)
end
end
else
-- For other actions (e.g., errors), the function directly prints the result.
print(result)
end
end
-- The `advance` function takes an optional integer parameter representing the player's choice index.
-- When calling this function for the first time or when no choice is needed, we pass nil.
advance = (option)->
-- The function first calls `runner\advance` to fetch the next part of the Yarn script.
-- This returns two values: an action type and a result.
action, result = runner\advance option
-- Based on the action type, we choose how to handle the result.
switch action when "Text"
-- If the action is "Text," the result will be a TextResult object,
-- which contains the text content and any associated marks (e.g., character names).
-- We check for marks, extract the character name (if present), and print the text content.
charName = ""
if result.marks
for mark in *result.marks
switch mark when {name: attr, attrs: {:name}}
charName = "#{name}: " if attr == "char"
print charName .. result.text
when "Option"
-- If the action is "Option," the result will be an OptionResult object,
-- which contains one or more options. The function iterates through these options and prints them,
-- which the player can choose later.
for i, op in ipairs result
print "[#{i}]: #{op.text}" if op
else
-- For other actions (e.g., errors), the function directly prints the result.
print result
3. Initiating the Narrative
To initiate the narrative, you simply call the advance
function without any arguments:
- Lua
- Teal
- YueScript
advance()
advance()
advance!
4. Responding to User Input
To allow player interaction with the narrative, we need a node to capture and respond to user input. We create a node and assign it a signal slot named "go." When this signal is triggered, it will call the advance
function again and pass the player's choice:
- Lua
- Teal
- YueScript
local node = Node()
node:gslot("go", function(option)
advance(option)
end)
node:addTo(Director.entry)
local node = Node()
node:gslot("go", function(option: nil | integer)
advance(option)
end)
node:addTo(Director.entry)
with Node!
\gslot "go", (option)-> advance option
\addTo Director.entry
In this example, a global event listener has been registered for quick testing. In actual game development, you would need to implement UI interaction logic. With the "go" global event listener, you can continue the dialogue by entering emit 'go'
in the Dora SSR console command line, and you can interactively test the conversation by entering emit 'go', 1
to select dialogue branches.
5. Conclusion
Now, you have set up all the necessary code to load and run Yarn narrative scripts. You can run the above scripts to start your interactive narrative, where players can interact by choosing options. Happy storytelling!